package com.example.demo.arithmetic.datastructure.heap;

import java.util.Arrays;

/**
 * 大顶堆
 */
public class BigHeap {
    int[] array;

    int size;

//    public BigHeap(int capacity) {
//        this.array = new int[capacity];
//        heapify();
//    }


    public BigHeap(int[] array) {
        this.array = array;
        this.size = array.length;
        heapify();
    }

    // 建堆
    private void heapify() {
        // 找到最后一个非叶子节点 size/2 - 1
        for (int i = size / 2 - 1; i >= 0; i--) {
            down(i);
        }

    }

    /**
     * 要下潜的索引值，与两个孩子较大者交换，直至没孩子或孩子没它大
     *
     * @param i
     */
    private void down(int i) {
        int left = i * 2 + 1;
        int right = left + 1;
        int max = i;
        if (left < size && array[left] > array[max]) {
            max = left;
        }
        if (right < size && array[right] > array[max]) {
            max = right;
        }

        if (max != i) {
            swap(max, i);
            down(max);
        }
    }

    private void up(int i) {
        int child = size;
        while (child > 0) {
            int parent = (child - 1) / 2;
            if (i > array[parent]) {
                array[child] = array[parent];
            } else {
                break;
            }
            child = parent;
        }
        array[child] = i;

    }

    private void swap(int max, int i) {
        int temp = array[max];
        array[max] = array[i];
        array[i] = temp;

    }

    public Integer peek() {
        if (size < 1) {
            return null;
        }
        return array[0];
    }

    public Integer poll() {

        int top = array[0];
        swap(0, size - 1);
        size--;
        down(0);
        return top;
    }

    public Integer poll(int index) {

        int deleted = array[index];
        swap(0, size - 1);
        size--;
        down(index);
        return deleted;
    }

    public void replace(int replaced) {
        array[0] = replaced;
        down(0);
    }

    public boolean offer(int i) {

        if (size == array.length) {
            return false;
        }
        up(i);
        size++;
        return true;
    }

    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5, 6, 7};
        BigHeap heap = new BigHeap(array);
        System.out.println(Arrays.toString(heap.array));
    }
}
